<template>
  <div class="process-drawer__layout" v-loading="loading">
    <div class="process-drawer__header g-flex-between-center">
      <div class="header__left">
        <span class="header__left-text">{{ title }} ({{ collapseCount }})</span>
      </div>
      <div
        class="header__right"
        v-if="props.lifeCycleStage !== 'TRANSFER_STAGE' && props.lifeCycleStage !== 'USE_STAGE'"
      >
        <div class="header__right-label"
          >以下数据对应的产品数量 <span class="header__right-label--required">*</span></div
        >
        <el-input
          ref="productNumRef"
          class="header__right-input"
          type="number"
          @wheel.stop.prevent
          v-model="headerRightFormState.productNum"
          placeholder="请输入"
          v-positive-only:6
          @keypress.enter="handleProductNumEnter"
          @blur="postUpdateProductReq"
          :disabled="!hasBtnPermission('PCF_PROCESS_DATA_EDIT')"
          v-loading="productNumLoading"
        >
          <template #append>
            <el-select
              class="header__right-input-select"
              v-model="headerRightFormState.productUnit"
              disabled
            >
              <el-option
                v-for="unit in modelUnitAllOption"
                :key="unit.value"
                :label="unit.label"
                :value="unit.value"
              />
            </el-select>
          </template>
        </el-input>
      </div>
    </div>
    <div class="process-drawer__body" ref="processDrawerBodyRef">
      <el-collapse
        class="drawer-body__collapse"
        v-model="activeCollapseName"
        accordion
        v-if="processList.length"
      >
        <el-collapse-item
          :name="item.processNo"
          v-for="(item, index) in processList"
          :key="item.processNo"
          :disabled="!!editingProcessNo"
        >
          <template #title>
            <div class="body-collapse__title-wrapper">
              <div class="body-collapse__title">
                <div class="collapse-title__icon-wrapper">
                  <CIcon
                    class="collapse-title__icon"
                    :class="
                      activeCollapseName === item.processNo ? 'collapse-title__icon--expanded' : ''
                    "
                    type="c-mian-you"
                  ></CIcon>
                </div>
                <el-input
                  class="collapse-title__input"
                  :ref="(el: HTMLElement) => setRefs(el, item.processNo)"
                  v-model="tempProcessName"
                  placeholder="请输入名称"
                  @keypress.enter.stop="handleInputBlur(item.processNo)"
                  @blur="handleSaveProcessName(item)"
                  v-if="editingProcessNo === item.processNo"
                ></el-input>
                <span class="collapse-title__text" v-else>{{ item.processName }}</span>
              </div>
              <div class="body-collapse__buttons" @click.stop>
                <CIconButton
                  class="collapse-buttons__btn"
                  icon="c-xian-bianji"
                  :content="collapseConfig.editBtnText"
                  v-if="hasBtnPermission('PCF_PROCESS_DATA_EDIT')"
                  @click="handleEditProcess(item)"
                ></CIconButton>
                <CIconButton
                  class="collapse-buttons__btn"
                  icon="c-xian-shanchu"
                  :content="collapseConfig.deleteBtnText"
                  v-if="hasBtnPermission('PCF_PROCESS_DATA_EDIT')"
                  @click="handleDeleteProcess(item.processNo, item.processDataList)"
                ></CIconButton>
              </div>
            </div>
          </template>
          <div class="body-collapse__content-wrapper">
            <slot name="content" :item="item" :index="index"></slot>
          </div>
        </el-collapse-item>
      </el-collapse>
      <el-button
        :class="processList?.length ? 'g-mt16' : ''"
        @click="handleAddProcess"
        v-btnPermission="'PCF_PROCESS_DATA_EDIT'"
        ><CIcon class="g-mr4" type="c-xian-xinjian"></CIcon
        >{{ collapseConfig.addBtnText }}</el-button
      >
    </div>
  </div>
</template>

<script lang="ts" setup name="ModelDetailDrawerBody">
import { defineProps, defineEmits, defineExpose, computed, reactive, ref, nextTick } from 'vue';
import {
  addProcess,
  editProcess,
  deleteProcess,
  getListProcessInfo,
  postUpdateProduct
} from '@/apis/pcf/myModel/modelDetail';
import type { ProcessListItem } from '@/apis/pcf/myModel/model/modelDetailModel';
import { useMessage } from '@/hooks/useMessage';
import { buildUUID } from '@/utils/uuid';
import { ProcessStageCodeEnum, modelUnitAllOption } from '@/constants/enum';
import type { CollapseConfig } from './types';
import { hasBtnPermission } from '@/directives/btnPermission';

interface CustomProcessListItem extends ProcessListItem {
  addingFlag?: boolean;
}

interface ModelDetailDrawerBodyProps {
  title: string;
  collapseConfig: CollapseConfig;
  lifeCycleStage: keyof typeof ProcessStageCodeEnum;
  modelNo: string;
}
const props = defineProps<ModelDetailDrawerBodyProps>();
const emits = defineEmits(['refresh']);

const { createMessage, createConfirm } = useMessage();
/**
 * 页面loading
 */
const loading = ref(false);

/**
 * 右侧数量及单位
 */
const headerRightFormState = reactive({
  productNum: null as unknown as number,
  productUnit: 'pcs'
});

const productNum = ref();

/**
 * 正在编辑的工序的工序编号
 */
const editingProcessNo = ref();
/**
 * 正在新增的工序的工序编号
 */
const addingProcessNo = ref();
const processDrawerBodyRef = ref();
const tempProcessName = ref();
const processNameInputRefs = ref<any>({});

const collapseCount = computed(() => {
  return processList.value.filter(n => !n.addingFlag).length;
});

function setRefs(el: HTMLElement, processNo: string) {
  processNameInputRefs.value[processNo] = el;
}

const productNumRef = ref();
function handleProductNumEnter() {
  productNumRef.value?.blur();
}

const productNumLoading = ref(false);
async function postUpdateProductReq() {
  if (Number(headerRightFormState.productNum) <= 0) {
    headerRightFormState.productNum = productNum.value;
    createMessage.error('产品数量需大于0');
    return;
  }
  if (headerRightFormState.productNum == productNum.value) {
    return;
  }
  try {
    productNumLoading.value = true;
    const params = {
      modelNo: props.modelNo,
      lifeCycleStage: props.lifeCycleStage,
      productNum: Number(headerRightFormState.productNum),
      productUnit: headerRightFormState.productUnit
    };
    await postUpdateProduct(params);
    productNum.value = headerRightFormState.productNum;
    productNumLoading.value = false;
  } catch (error) {
    console.log('error', error);
    headerRightFormState.productNum = productNum.value;
    productNumLoading.value = false;
  }
}

/**
 * 新增工序
 */
function handleAddProcess() {
  const uuid = buildUUID();
  addingProcessNo.value = uuid;
  const generateProcessItem = {
    addingFlag: true,
    processNo: addingProcessNo.value,
    processName: '',
    processDataList: []
  };
  processList.value.push(generateProcessItem);
  // 打开折叠面板，出现工序名称输入框并聚焦输入框
  handleEditProcess(generateProcessItem);
  nextTick(() => {
    // 滚动页面到底部
    let scrollElem = processDrawerBodyRef.value; // 对应ref的命名
    scrollElem.scrollTo({ top: scrollElem.scrollHeight, behavior: 'smooth' });
  });
}

/**
 * 编辑工序
 * NOTE 打开折叠面板，出现工序名称输入框并聚焦输入框
 */
function handleEditProcess(item: CustomProcessListItem) {
  // 展开折叠面板
  activeCollapseName.value = item.processNo;
  // 正在编辑的工序编号
  editingProcessNo.value = item.processNo;
  // 输入框的内容
  tempProcessName.value = item.processName;
  // 聚焦输入框
  nextTick(() => {
    processNameInputRefs.value[item.processNo]?.focus();
  });
}

/**
 * 删除工序
 */
function handleDeleteProcess(processNo: string, dataList: ProcessListItem['processDataList']) {
  if (!dataList?.length) {
    handleDeleteProcessReq(processNo);
    return;
  }
  // 产品使用阶段
  let msg = '确认删除使用情景？';
  if (props.lifeCycleStage === 'MANUFACTURE_STAGE') {
    // 产品生产阶段
    msg = '确认删除生产过程？';
  } else if (props.lifeCycleStage === 'TRANSFER_STAGE') {
    // 产品运输阶段
    msg = '确认删除运输场景？';
  }
  createConfirm('提示', msg, {
    iconType: 'warning',
    confirmButtonText: '删除'
  }).then(() => {
    handleDeleteProcessReq(processNo);
  });
}

/**
 * 删除工序接口请求逻辑
 * @param processNo
 */
async function handleDeleteProcessReq(processNo: string) {
  try {
    loading.value = true;
    await deleteProcess(processNo);
    const index = processList.value.findIndex(n => n.processNo === processNo);
    if (index > -1) {
      processList.value.splice(index, 1);
      createMessage.success('删除成功！');
      if (!processList.value?.length) {
        // 删除最后一个工序时
        activeCollapseName.value = '';
      } else if (activeCollapseName.value === processNo) {
        activeCollapseName.value = processList.value[0].processNo || '';
      }
      handleRefresh();
    }
    loading.value = false;
  } catch (error) {
    console.log('error', error);
    loading.value = false;
  }
}

/**
 * 保存工序名称
 * 新增/编辑
 */
async function handleSaveProcessName(item: CustomProcessListItem) {
  // 输入框内没有文字
  if (!tempProcessName.value) {
    // 新增操作，取消新增
    if (addingProcessNo.value === item.processNo) {
      addingProcessNo.value = '';
      const index = processList.value.findIndex(n => n.processNo === item.processNo);
      if (index > -1) {
        processList.value.splice(index, 1);
      }
      activeCollapseName.value = processList.value[0]?.processNo || '';
      return;
    }
    // 编辑操作，还原
    if (editingProcessNo.value === item.processNo) {
      tempProcessName.value = item.processName;
      editingProcessNo.value = undefined;
      return;
    }
  }
  try {
    loading.value = true;
    // 新增
    if (addingProcessNo.value === item.processNo) {
      const params = {
        modelNo: props.modelNo,
        lifeCycleStage: props.lifeCycleStage,
        processName: tempProcessName.value
      };
      const processResult = await addProcess(params);
      item.processNo = processResult.processNo;
      activeCollapseName.value = item.processNo;
      item.addingFlag = false;
      handleRefresh();
    } else {
      // 编辑
      const params = {
        processNo: item.processNo,
        processName: tempProcessName.value
      };
      await editProcess(params);
    }
    item.processName = tempProcessName.value;
    editingProcessNo.value = undefined;
    loading.value = false;
  } catch (error) {
    editingProcessNo.value = undefined;
    if (addingProcessNo.value === item.processNo) {
      addingProcessNo.value = '';
      const index = processList.value.findIndex(n => n.processNo === item.processNo);
      if (index > -1) {
        processList.value.splice(index, 1);
      }
    }
    loading.value = false;
  }
}

/**
 * 输入框回车触发失焦事件
 */
function handleInputBlur(processNo: string) {
  processNameInputRefs.value[processNo]?.blur();
}

/**
 * 当前激活的collapse
 */
const activeCollapseName = ref();

/**
 * 列表数据
 */
const processList = ref<CustomProcessListItem[]>([]);

/**
 * 获取列表数据
 * @param processNo 用于刷新某一个process
 */
async function getData(processNo?: string) {
  console.log('getData');
  try {
    loading.value = true;
    const params = {
      modelNo: props.modelNo,
      lifeCycleStage: props.lifeCycleStage
    };
    if (processNo) {
      Object.assign(params, {
        processNo: processNo
      });
    }
    const res = await getListProcessInfo(params);
    if (Object.keys(res).length) {
      // 刷新某一个process
      if (processNo) {
        const refreshIndex = processList.value.findIndex(n => n.processNo === processNo);
        if (refreshIndex > -1) {
          processList.value[refreshIndex] = res.processList[0] || [];
        } else {
          processList.value.push(res.processList[0] || []);
        }
        activeCollapseName.value = processNo;
      } else {
        headerRightFormState.productNum = res.productNum;
        headerRightFormState.productUnit = res.productUnit;
        productNum.value = res.productNum;
        processList.value = res.processList;
        activeCollapseName.value = processList.value[0]?.processNo || '';
      }
    }
    loading.value = false;
  } catch (error) {
    loading.value = false;
    console.log('error', error);
  }
}

/**
 * 用户刷新总览数量
 */
function handleRefresh() {
  emits('refresh');
}

// NOTE 由于父页面是用v-if判断的，所以这个组件每次都会渲染
getData();

defineExpose({
  getData,
  productNum
});
</script>

<style lang="scss" scoped>
.process-drawer__layout {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  .process-drawer__header {
    padding: 0 24px;
    height: 56px;
    background: #ffffff;
    border-bottom: 1px solid #f0f4f7;
    .header__left-text {
      font-size: 14px;
      font-family: PingFangSC-Medium, PingFang SC;
      font-weight: 500;
      color: #0a1f33;
      line-height: 22px;
    }
    .header__right {
      display: flex;
      align-items: center;
      .header__right-label {
        margin-right: 12px;
        font-size: 14px;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: #0a1f33;
        line-height: 22px;
        .header__right-label--required {
          color: #ff4829;
        }
      }
      .header__right-input {
        width: 300px;
        .header__right-input-select {
          width: 120px;
        }
      }
    }
  }
  .process-drawer__body {
    flex: 1;
    padding: 16px;
    width: 100%;
    background-color: #f3f7fb;
    overflow: auto;
    :deep(.drawer-body__collapse.el-collapse) {
      --el-collapse-border-color: #f0f4f7;
      .el-collapse-item {
        position: relative;
        border-radius: 6px;
        overflow: hidden;
        &::before {
          content: '';
          left: 0;
          top: 0;
          position: absolute;
          width: 2px;
          height: 100%;
          background-color: #03ac82;
        }
      }
      .el-collapse-item + .el-collapse-item {
        margin-top: 16px;
      }
      .el-collapse-item__content {
        padding-bottom: 0;
      }
      .el-collapse-item__arrow {
        display: none;
      }
      .body-collapse__title-wrapper {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 0 0 0 16px;
        width: 100%;
        .body-collapse__title {
          flex: 1;
          display: flex;
          align-items: center;
          .collapse-title__icon-wrapper {
            margin-right: 6px;
            width: 16px;
            height: 16px;
            display: flex;
            align-items: center;
            justify-content: center;
            .collapse-title__icon {
              font-size: 12px;
              transition: transform 0.3s;
              &.collapse-title__icon--expanded {
                transform: rotate(90deg);
              }
            }
          }
          .collapse-title__input {
            padding-right: 16px;
          }
          .collapse-title__text {
            font-size: 14px;
            font-family: PingFangSC-Medium, PingFang SC;
            font-weight: 500;
            color: #0a1f33;
            line-height: 22px;
          }
        }
        .body-collapse__buttons {
          padding: 0 16px;
          flex-shrink: 0;
          .collapse-buttons__btn + .collapse-buttons__btn {
            margin-left: 8px;
          }
        }
      }
      .body-collapse__content-wrapper {
        padding: 0 16px 20px;
        .collapse-content__header {
          padding-bottom: 12px;
        }
      }
    }
  }
}
</style>
